package cn.edu.neu.vmmigeval.evaluation.loadevaluation;


import cn.edu.neu.vmmigeval.cloud.entity.Host;
import cn.edu.neu.vmmigeval.cloud.entity.Vm;

import java.util.List;

public class HostLoadEvaluation {
	
	private int hostNum;
	List<Host> hosts;
	
	public HostLoadEvaluation(){
		
	}
	
	public HostLoadEvaluation( List<Host> hosts) {
		if(hosts==null){
			hostNum=0;
		}else{
			this.hosts = hosts;
			hostNum = hosts.size();
		}
	}
	public double getOneValue(double current,double total,int param){
		double result = (double)(current/total) *param;
		return result;
	}
	//得到矩阵X
	public double[][] getXMatrix(){
		int hostSize = hosts.size();
		double matrix[][] = new double[hostSize][8];
		for (int i = 0; i < hostSize; i++) {
			for (int j = 0; j < 8; j++) {
				if(j==0){
					matrix[i][j] = getOneValue(hosts.get(i).getCurrentCpu(),hosts.get(i).getTotalCpu(),100);
				}else if(j==1){
					matrix[i][j] = getOneValue(hosts.get(i).getCurrentRam(),hosts.get(i).getTotalRam(),100);
				}else if(j==2){
					matrix[i][j] = getOneValue(hosts.get(i).getCurrentBw(),hosts.get(i).getTotalBw(),100);
				}else if(j==3){
					matrix[i][j] = getOneValue(hosts.get(i).getCurrentDisk(),hosts.get(i).getTotalDisk(),100);
				}else if(j==4){
					matrix[i][j] = hosts.get(i).getCurrentCpu();
				}else if(j==5){
					matrix[i][j] = hosts.get(i).getCurrentRam();
				}else if(j==6){
					matrix[i][j] = hosts.get(i).getCurrentBw();
				}else if(j==7){
					List<Vm> vms = hosts.get(i).getVmList();
					matrix[i][j] = vms==null?0:vms.size();
				}
			}
		}
		/*matrix = new double[][]{
				{22,14,33,16,2000,2048,1024,2},
				{36,34,25,48,2400,2048,1024,3},
				{52,58,26,55,2800,4096,1024,3},
				{86,65,58,77,3200,4096,1024,5}
				};*/
		return matrix;
	}
	//得到，归一化之后的矩阵X'
	public double[][] getXSMatrix(){
		double[][] matrix = getXMatrix();
		double[][] xsMatrix = new double[hostNum][8];
		//每一列的总和
		double[] eachRowSum = new double[8];
		for (int i = 0; i < hostNum; i++) {
			for (int j = 0; j < 8; j++) {
				eachRowSum[j]+= matrix[i][j];
			}
		}
		//归一化的矩阵
		for (int i = 0; i < hostNum; i++) {
			for (int j = 0; j < 8; j++) {
				xsMatrix[i][j] =  matrix[i][j]/eachRowSum[j];
			}
		}
		return xsMatrix;
	}
	//构造权重矩阵
	public double[][] getHostWeightedMatrix(){
		double[][] weightedMatrix = new double[8][8];
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				if(i==j&&i==0){
					weightedMatrix[i][j] = 0.3;
				}else if(i==j){
					weightedMatrix[i][j] = 0.1;
				}else{
					weightedMatrix[i][j] = 0;
				}
			}
		}
		return weightedMatrix;
	}
	//得到加权之后的矩阵
	public double[][] getXSWeightedMatrix(){
		//double[][] weightedMatrix = getHostWeightedMatrix();
		double[][] xsMatrix = getXSMatrix();
		double[] weightedMatrix = new double[]{0.3,0.1,0.1,0.1,0.1,0.1,0.1,0.1};
		double[][] xsWeightedMatrix = new double[hostNum][8];
		//矩阵相乘
		for (int i = 0; i < hostNum; i++) {
			for (int j = 0; j < 8; j++) {
				xsWeightedMatrix[i][j]= xsMatrix[i][j]*weightedMatrix[j];
			}
		}
		return xsWeightedMatrix;
	}
	public double[] getBest(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] z = new double[]{0,0,0,0,1,1,1,0};
		for (int i = 0; i < 8; i++) {
			//System.out.println("length is :"+xsWeightedMatrix.length);
			for (int j = 0; j < xsWeightedMatrix.length; j++) {
				if(i<4||i>6){
					if(xsWeightedMatrix[j][i]>z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}else{
					if(xsWeightedMatrix[j][i]<z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}
			}
			
		}
		return z;
	}
	public double[] getWorst(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] z = new double[]{1,1,1,1,0,0,0,1};
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < xsWeightedMatrix.length; j++) {
				if(j<4||j>6){
					if(xsWeightedMatrix[j][i]<z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}else{
					if(xsWeightedMatrix[j][i]>z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}
			}
			
		}
		return z;
	}
	//得到最好距离差
	public double[] getBestS(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] best = getBest();
		double[] bestS = new double[hostNum];
		double sumBest =0 ;
		for (int i = 0; i < hostNum; i++) {
			sumBest =0;
			for (int j = 0; j < 8; j++) {
				double pa =  xsWeightedMatrix[i][j]-best[j];
				sumBest+=pa*pa;
			}
			bestS[i] = Math.sqrt(sumBest);
		}
		return bestS;
		
	}
	//得到最坏距离差
	public double[] getWorstS(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] worst = getWorst();
		double[] worstS = new double[hostNum];
		double sumWorst =0;
		for (int i = 0; i < hostNum; i++) {
			sumWorst =0;
			for (int j = 0; j < 8; j++) {
				double pb =  xsWeightedMatrix[i][j]-worst[j];
				sumWorst+=pb*pb;
			}
			worstS[i] = Math.sqrt(sumWorst);
		}
		return worstS;
	}
	public double[] getFinal(){
	//	System.out.println("-------------------");
		double[] bestS = getBestS();
	/*	for (int i = 0; i < bestS.length; i++) {
			System.out.println(bestS[i]);
		}
		System.out.println();
		*/
		double[] worstS = getWorstS();
		/*
		for (int i = 0; i < bestS.length; i++) {
			System.out.println(worstS[i]);
		}
		System.out.println("-------------------");
		*/
		double[] finalS = new double[hostNum];
		for (int i = 0; i < hostNum; i++) {
			finalS[i] = worstS[i]/(bestS[i]+worstS[i]);
			hosts.get(i).setScore(finalS[i]);
		}
		return finalS;
	}
	/*public static void main(String[] args) {
		List<Host> hosts = new ArrayList<Host>();
		hosts.add(new Host());
		hosts.add(new Host());
		hosts.add(new Host());
		hosts.add(new Host());
		HostLoadEvaluation le = new HostLoadEvaluation(hosts);
		le.getFinal();
		for (Host host : hosts) {
			System.out.println(host.getScore());
		}
		
	}*/
	
}
